--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
Node / ReticulumProjects / MeshChatX.git / files / meshchatx / src / backend / persistent_log_handler.py
Displaying Raw • Download
meshchatx/src/backend/persistent_log_handler.py 9d8611bb97df55bcb1fb38bc6de17e9f7846ffa2 (9d8611bb) Text, 8.01 KB
Tff7b72import T7ee787collections
Tff7b72import T7ee787logging
Tff7b72import T7ee787re
Tff7b72import T7ee787threading
Tff7b72import T7ee787time
Tff7b72from T7ee787datetime Tff7b72import Te6edf3UTCTb4b4b4, Te6edf3datetime
Tff7b72class T56d364PersistentLogHandlerTb4b4b4(Te6edf3loggingTff7b72.Td2a8ffHandlerTb4b4b4)Tb4b4b4:
Tff7b72def Tff7b72__init__Tb4b4b4(Tff7b72selfTb4b4b4, Te6edf3databaseTff7b72=Tff7b72NoneTb4b4b4, Te6edf3capacityTff7b72=T79c0ff5000Tb4b4b4, Te6edf3flush_intervalTff7b72=T79c0ff5Tb4b4b4)Tb4b4b4:
Tffa657superTb4b4b4(Tb4b4b4)Tff7b72.Td2a8ff__init__Tb4b4b4(Tb4b4b4)
Tff7b72selfTff7b72.Td2a8ffdatabase Tff7b72= Te6edf3database
Tff7b72selfTff7b72.Td2a8fflogs_buffer Tff7b72= Te6edf3collectionsTff7b72.Td2a8ffdequeTb4b4b4(Te6edf3maxlenTff7b72=Te6edf3capacityTb4b4b4)
Tff7b72selfTff7b72.Td2a8ffflush_interval Tff7b72= Te6edf3flush_interval
Tff7b72selfTff7b72.Td2a8fflast_flush_time Tff7b72= Te6edf3timeTff7b72.Td2a8fftimeTb4b4b4(Tb4b4b4)
Tff7b72selfTff7b72.Td2a8fflock Tff7b72= Te6edf3threadingTff7b72.Td2a8ffRLockTb4b4b4(Tb4b4b4)
Tff7b72selfTff7b72.Td2a8ffflush_lock Tff7b72= Te6edf3threadingTff7b72.Td2a8ffLockTb4b4b4(Tb4b4b4)
T8b949e# Anomaly detection state
Tff7b72selfTff7b72.Td2a8ffrecent_messages Tff7b72= Te6edf3collectionsTff7b72.Td2a8ffdequeTb4b4b4(Te6edf3maxlenTff7b72=T79c0ff100Tb4b4b4)
Tff7b72selfTff7b72.Td2a8ffflooding_threshold Tff7b72= T79c0ff20 T8b949e# messages per second
Tff7b72selfTff7b72.Td2a8ffrepeat_threshold Tff7b72= T79c0ff5 T8b949e# identical messages in a row
Tff7b72selfTff7b72.Td2a8ffmessage_counts Tff7b72= Te6edf3collectionsTff7b72.Td2a8ffdefaultdictTb4b4b4(Tffa657intTb4b4b4)
Tff7b72selfTff7b72.Td2a8fflast_reset_time Tff7b72= Te6edf3timeTff7b72.Td2a8fftimeTb4b4b4(Tb4b4b4)
T8b949e# UA and IP tracking
Tff7b72selfTff7b72.Td2a8ffknown_ips Tff7b72= Tffa657setTb4b4b4(Tb4b4b4)
Tff7b72selfTff7b72.Td2a8ffknown_uas Tff7b72= Tffa657setTb4b4b4(Tb4b4b4)
Tff7b72def Td2a8ffset_databaseTb4b4b4(Tff7b72selfTb4b4b4, Te6edf3databaseTb4b4b4)Tb4b4b4:
Tff7b72with Tff7b72selfTff7b72.Td2a8fflockTb4b4b4:
Tff7b72selfTff7b72.Td2a8ffdatabase Tff7b72= Te6edf3database
Tff7b72def Td2a8ffemitTb4b4b4(Tff7b72selfTb4b4b4, Te6edf3recordTb4b4b4)Tb4b4b4:
Tff7b72tryTb4b4b4:
Te6edf3msg Tff7b72= Tff7b72selfTff7b72.Td2a8ffformatTb4b4b4(Te6edf3recordTb4b4b4)
Te6edf3timestamp Tff7b72= Te6edf3datetimeTff7b72.Td2a8ffnowTb4b4b4(Te6edf3UTCTb4b4b4)Tff7b72.Td2a8fftimestampTb4b4b4(Tb4b4b4)
Te6edf3is_anomalyTb4b4b4, Te6edf3anomaly_type Tff7b72= Tff7b72selfTff7b72.Td2a8ff_detect_anomalyTb4b4b4(Te6edf3recordTb4b4b4, Te6edf3msgTb4b4b4, Te6edf3timestampTb4b4b4)
Te6edf3log_entry Tff7b72= Tb4b4b4{
Ta5d6ff"Ta5d6fftimestampTa5d6ff"Tb4b4b4: Te6edf3timestampTb4b4b4,
Ta5d6ff"Ta5d6fflevelTa5d6ff"Tb4b4b4: Te6edf3recordTff7b72.Td2a8fflevelnameTb4b4b4,
Ta5d6ff"Ta5d6ffmoduleTa5d6ff"Tb4b4b4: Te6edf3recordTff7b72.Td2a8ffmoduleTb4b4b4,
Ta5d6ff"Ta5d6ffmessageTa5d6ff"Tb4b4b4: Te6edf3msgTb4b4b4,
Ta5d6ff"Ta5d6ffis_anomalyTa5d6ff"Tb4b4b4: T79c0ff1 Tff7b72if Te6edf3is_anomaly Tff7b72else T79c0ff0Tb4b4b4,
Ta5d6ff"Ta5d6ffanomaly_typeTa5d6ff"Tb4b4b4: Te6edf3anomaly_typeTb4b4b4,
Tb4b4b4}
Tff7b72with Tff7b72selfTff7b72.Td2a8fflockTb4b4b4:
Tff7b72selfTff7b72.Td2a8fflogs_bufferTff7b72.Td2a8ffappendTb4b4b4(Te6edf3log_entryTb4b4b4)
T8b949e# Periodically flush to database if available
Tff7b72if Tff7b72selfTff7b72.Td2a8ffdatabase Tff7b72and Tb4b4b4(
Te6edf3timeTff7b72.Td2a8fftimeTb4b4b4(Tb4b4b4) Tff7b72- Tff7b72selfTff7b72.Td2a8fflast_flush_time Tff7b72> Tff7b72selfTff7b72.Td2a8ffflush_interval
Tb4b4b4)Tb4b4b4:
Tff7b72selfTff7b72.Td2a8ff_flush_to_dbTb4b4b4(Tb4b4b4)
Tff7b72except Tf85149ExceptionTb4b4b4:
Tff7b72selfTff7b72.Td2a8ffhandleErrorTb4b4b4(Te6edf3recordTb4b4b4)
Tff7b72def Td2a8ff_detect_access_anomalyTb4b4b4(Tff7b72selfTb4b4b4, Te6edf3messageTb4b4b4)Tb4b4b4:
T8b949e"""Detect anomalies in aiohttp access logs."""
T8b949e# Regex to extract IP and User-Agent from aiohttp access log
T8b949e# Format: IP [date] "GET ..." status size "referer" "User-Agent"
Te6edf3match Tff7b72= Te6edf3reTff7b72.Td2a8ffsearchTb4b4b4(
Ta5d6ffrTa5d6ff"Ta5d6ff^([Ta5d6ff\Ta5d6ffdTa5d6ff\Ta5d6ff.Ta5d6ff\Ta5d6ff:]+) .* Tffea00\"Ta5d6ff[^Tffea00\"Ta5d6ff]+Tffea00\"Ta5d6ff Ta5d6ff\Ta5d6ffd+ Ta5d6ff\Ta5d6ffd+ Tffea00\"Ta5d6ff[^Tffea00\"Ta5d6ff]*Tffea00\"Ta5d6ff Tffea00\"Ta5d6ff([^Tffea00\"Ta5d6ff]+)Tffea00\"Ta5d6ff"Tb4b4b4, Te6edf3message
Tb4b4b4)
Tff7b72if Te6edf3matchTb4b4b4:
Te6edf3ip Tff7b72= Te6edf3matchTff7b72.Td2a8ffgroupTb4b4b4(T79c0ff1Tb4b4b4)
Te6edf3ua Tff7b72= Te6edf3matchTff7b72.Td2a8ffgroupTb4b4b4(T79c0ff2Tb4b4b4)
Tff7b72with Tff7b72selfTff7b72.Td2a8fflockTb4b4b4:
Te6edf3is_anomaly Tff7b72= Tff7b72False
Te6edf3anomaly_type Tff7b72= Tff7b72None
T8b949e# Detect if this is a different UA or IP from what we've seen recently
Tff7b72if Tffa657lenTb4b4b4(Tff7b72selfTff7b72.Td2a8ffknown_ipsTb4b4b4) Tff7b72> T79c0ff0 Tff7b72and Te6edf3ip Tff7b72not Tff7b72in Tff7b72selfTff7b72.Td2a8ffknown_ipsTb4b4b4:
Te6edf3is_anomaly Tff7b72= Tff7b72True
Te6edf3anomaly_type Tff7b72= Ta5d6ff"Ta5d6ffmulti_ipTa5d6ff"
Tff7b72if Tffa657lenTb4b4b4(Tff7b72selfTff7b72.Td2a8ffknown_uasTb4b4b4) Tff7b72> T79c0ff0 Tff7b72and Te6edf3ua Tff7b72not Tff7b72in Tff7b72selfTff7b72.Td2a8ffknown_uasTb4b4b4:
Te6edf3is_anomaly Tff7b72= Tff7b72True
Tff7b72if Te6edf3anomaly_typeTb4b4b4:
Te6edf3anomaly_type Tff7b72= Ta5d6ff"Ta5d6ffmulti_ip_uaTa5d6ff"
Tff7b72elseTb4b4b4:
Te6edf3anomaly_type Tff7b72= Ta5d6ff"Ta5d6ffmulti_uaTa5d6ff"
Tff7b72selfTff7b72.Td2a8ffknown_ipsTff7b72.Td2a8ffaddTb4b4b4(Te6edf3ipTb4b4b4)
Tff7b72selfTff7b72.Td2a8ffknown_uasTff7b72.Td2a8ffaddTb4b4b4(Te6edf3uaTb4b4b4)
T8b949e# Cap the tracking sets to prevent memory growth
Tff7b72if Tffa657lenTb4b4b4(Tff7b72selfTff7b72.Td2a8ffknown_ipsTb4b4b4) Tff7b72> T79c0ff100Tb4b4b4:
Tff7b72selfTff7b72.Td2a8ffknown_ipsTff7b72.Td2a8ffclearTb4b4b4(Tb4b4b4)
Tff7b72if Tffa657lenTb4b4b4(Tff7b72selfTff7b72.Td2a8ffknown_uasTb4b4b4) Tff7b72> T79c0ff100Tb4b4b4:
Tff7b72selfTff7b72.Td2a8ffknown_uasTff7b72.Td2a8ffclearTb4b4b4(Tb4b4b4)
Tff7b72return Te6edf3is_anomalyTb4b4b4, Te6edf3anomaly_type
Tff7b72return Tff7b72FalseTb4b4b4, Tff7b72None
Tff7b72def Td2a8ff_detect_anomalyTb4b4b4(Tff7b72selfTb4b4b4, Te6edf3recordTb4b4b4, Te6edf3messageTb4b4b4, Te6edf3timestampTb4b4b4)Tb4b4b4:
T8b949e# 1. Access anomaly detection (UA/IP) - checked for all levels of aiohttp.access
Tff7b72if Te6edf3recordTff7b72.Td2a8ffname Tff7b72== Ta5d6ff"Ta5d6ffaiohttp.accessTa5d6ff"Tb4b4b4:
Te6edf3is_acc_anomalyTb4b4b4, Te6edf3acc_type Tff7b72= Tff7b72selfTff7b72.Td2a8ff_detect_access_anomalyTb4b4b4(Te6edf3messageTb4b4b4)
Tff7b72if Te6edf3is_acc_anomalyTb4b4b4:
Tff7b72return Tff7b72TrueTb4b4b4, Te6edf3acc_type
T8b949e# Only detect other anomalies for WARNING level and above
Tff7b72if Te6edf3recordTff7b72.Td2a8fflevelno Tff7b72< Te6edf3loggingTff7b72.Td2a8ffWARNINGTb4b4b4:
Tff7b72return Tff7b72FalseTb4b4b4, Tff7b72None
Te6edf3now Tff7b72= Te6edf3timeTff7b72.Td2a8fftimeTb4b4b4(Tb4b4b4)
T8b949e# 1. Detect Log Flooding
Tff7b72if Te6edf3now Tff7b72- Tff7b72selfTff7b72.Td2a8fflast_reset_time Tff7b72> T79c0ff1.0Tb4b4b4:
Tff7b72selfTff7b72.Td2a8ffmessage_countsTff7b72.Td2a8ffclearTb4b4b4(Tb4b4b4)
Tff7b72selfTff7b72.Td2a8fflast_reset_time Tff7b72= Te6edf3now
Tff7b72selfTff7b72.Td2a8ffmessage_countsTb4b4b4[Ta5d6ff"Ta5d6fftotalTa5d6ff"Tb4b4b4] Tff7b72+Tff7b72= T79c0ff1
Tff7b72if Tff7b72selfTff7b72.Td2a8ffmessage_countsTb4b4b4[Ta5d6ff"Ta5d6fftotalTa5d6ff"Tb4b4b4] Tff7b72> Tff7b72selfTff7b72.Td2a8ffflooding_thresholdTb4b4b4:
Tff7b72return Tff7b72TrueTb4b4b4, Ta5d6ff"Ta5d6fffloodingTa5d6ff"
T8b949e# 2. Detect Repeats
Tff7b72if Tffa657lenTb4b4b4(Tff7b72selfTff7b72.Td2a8ffrecent_messagesTb4b4b4) Tff7b72> T79c0ff0Tb4b4b4:
Te6edf3repeat_count Tff7b72= T79c0ff0
Tff7b72for Te6edf3prev_msg Tff7b72in Tffa657reversedTb4b4b4(Tff7b72selfTff7b72.Td2a8ffrecent_messagesTb4b4b4)Tb4b4b4:
Tff7b72if Te6edf3prev_msg Tff7b72== Te6edf3messageTb4b4b4:
Te6edf3repeat_count Tff7b72+Tff7b72= T79c0ff1
Tff7b72elseTb4b4b4:
Tff7b72break
Tff7b72if Te6edf3repeat_count Tff7b72>Tff7b72= Tff7b72selfTff7b72.Td2a8ffrepeat_thresholdTb4b4b4:
Tff7b72return Tff7b72TrueTb4b4b4, Ta5d6ff"Ta5d6ffrepeatTa5d6ff"
Tff7b72selfTff7b72.Td2a8ffrecent_messagesTff7b72.Td2a8ffappendTb4b4b4(Te6edf3messageTb4b4b4)
Tff7b72return Tff7b72FalseTb4b4b4, Tff7b72None
Tff7b72def Td2a8ff_flush_to_dbTb4b4b4(Tff7b72selfTb4b4b4)Tb4b4b4:
Tff7b72if Tff7b72not Tff7b72selfTff7b72.Td2a8ffdatabaseTb4b4b4:
Tff7b72return
T8b949e# Ensure only one thread flushes at a time
Tff7b72if Tff7b72not Tff7b72selfTff7b72.Td2a8ffflush_lockTff7b72.Td2a8ffacquireTb4b4b4(Te6edf3blockingTff7b72=Tff7b72FalseTb4b4b4)Tb4b4b4:
Tff7b72return
Tff7b72tryTb4b4b4:
Te6edf3items_to_flush Tff7b72= Tb4b4b4[Tb4b4b4]
Tff7b72with Tff7b72selfTff7b72.Td2a8fflockTb4b4b4:
Tff7b72while Tff7b72selfTff7b72.Td2a8fflogs_bufferTb4b4b4:
Te6edf3items_to_flushTff7b72.Td2a8ffappendTb4b4b4(Tff7b72selfTff7b72.Td2a8fflogs_bufferTff7b72.Td2a8ffpopleftTb4b4b4(Tb4b4b4)Tb4b4b4)
Tff7b72if Tff7b72not Te6edf3items_to_flushTb4b4b4:
Tff7b72return
T8b949e# Batch insert for speed
Tff7b72for Te6edf3entry Tff7b72in Te6edf3items_to_flushTb4b4b4:
Tff7b72tryTb4b4b4:
Tff7b72selfTff7b72.Td2a8ffdatabaseTff7b72.Td2a8ffdebug_logsTff7b72.Td2a8ffinsert_logTb4b4b4(
Te6edf3levelTff7b72=Te6edf3entryTb4b4b4[Ta5d6ff"Ta5d6fflevelTa5d6ff"Tb4b4b4]Tb4b4b4,
Te6edf3moduleTff7b72=Te6edf3entryTb4b4b4[Ta5d6ff"Ta5d6ffmoduleTa5d6ff"Tb4b4b4]Tb4b4b4,
Te6edf3messageTff7b72=Te6edf3entryTb4b4b4[Ta5d6ff"Ta5d6ffmessageTa5d6ff"Tb4b4b4]Tb4b4b4,
Te6edf3is_anomalyTff7b72=Te6edf3entryTb4b4b4[Ta5d6ff"Ta5d6ffis_anomalyTa5d6ff"Tb4b4b4]Tb4b4b4,
Te6edf3anomaly_typeTff7b72=Te6edf3entryTb4b4b4[Ta5d6ff"Ta5d6ffanomaly_typeTa5d6ff"Tb4b4b4]Tb4b4b4,
Tb4b4b4)
Tff7b72except Tf85149Exception Tff7b72as Te6edf3eTb4b4b4:
Tffa657printTb4b4b4(Ta5d6fffTa5d6ff"Ta5d6ffError inserting log: Tffd700{Te6edf3eTffd700}Ta5d6ff"Tb4b4b4)
T8b949e# Periodic cleanup of old logs (only every 100 flushes or similar?
T8b949e# for now let's just keep it here but it should be fast)
Tff7b72tryTb4b4b4:
Tff7b72selfTff7b72.Td2a8ffdatabaseTff7b72.Td2a8ffdebug_logsTff7b72.Td2a8ffcleanup_old_logsTb4b4b4(Tb4b4b4)
Tff7b72except Tf85149Exception Tff7b72as Te6edf3eTb4b4b4:
Tffa657printTb4b4b4(Ta5d6fffTa5d6ff"Ta5d6ffError cleaning up logs: Tffd700{Te6edf3eTffd700}Ta5d6ff"Tb4b4b4)
Tff7b72selfTff7b72.Td2a8fflast_flush_time Tff7b72= Te6edf3timeTff7b72.Td2a8fftimeTb4b4b4(Tb4b4b4)
Tff7b72except Tf85149Exception Tff7b72as Te6edf3eTb4b4b4:
Tffa657printTb4b4b4(Ta5d6fffTa5d6ff"Ta5d6ffFailed to flush logs to database: Tffd700{Te6edf3eTffd700}Ta5d6ff"Tb4b4b4)
Tff7b72finallyTb4b4b4:
Tff7b72selfTff7b72.Td2a8ffflush_lockTff7b72.Td2a8ffreleaseTb4b4b4(Tb4b4b4)
Tff7b72def Td2a8ffget_logsTb4b4b4(
Tff7b72selfTb4b4b4, Te6edf3limitTff7b72=T79c0ff100Tb4b4b4, Te6edf3offsetTff7b72=T79c0ff0Tb4b4b4, Te6edf3searchTff7b72=Tff7b72NoneTb4b4b4, Te6edf3levelTff7b72=Tff7b72NoneTb4b4b4, Te6edf3moduleTff7b72=Tff7b72NoneTb4b4b4, Te6edf3is_anomalyTff7b72=Tff7b72None
Tb4b4b4)Tb4b4b4:
Tff7b72if Tff7b72selfTff7b72.Td2a8ffdatabaseTb4b4b4:
T8b949e# Flush current buffer first to ensure we have latest logs
Tff7b72selfTff7b72.Td2a8ff_flush_to_dbTb4b4b4(Tb4b4b4)
Tff7b72with Tff7b72selfTff7b72.Td2a8fflockTb4b4b4:
Tff7b72if Tff7b72selfTff7b72.Td2a8ffdatabaseTb4b4b4:
Tff7b72return Tff7b72selfTff7b72.Td2a8ffdatabaseTff7b72.Td2a8ffdebug_logsTff7b72.Td2a8ffget_logsTb4b4b4(
Te6edf3limitTff7b72=Te6edf3limitTb4b4b4,
Te6edf3offsetTff7b72=Te6edf3offsetTb4b4b4,
Te6edf3searchTff7b72=Te6edf3searchTb4b4b4,
Te6edf3levelTff7b72=Te6edf3levelTb4b4b4,
Te6edf3moduleTff7b72=Te6edf3moduleTb4b4b4,
Te6edf3is_anomalyTff7b72=Te6edf3is_anomalyTb4b4b4,
Tb4b4b4)
Tff7b72elseTb4b4b4:
T8b949e# Fallback to in-memory buffer if DB not yet available
Te6edf3logs Tff7b72= Tffa657listTb4b4b4(Tff7b72selfTff7b72.Td2a8fflogs_bufferTb4b4b4)
Tff7b72if Te6edf3searchTb4b4b4:
Te6edf3logs Tff7b72= Tb4b4b4[
Te6edf3log
Tff7b72for Te6edf3log Tff7b72in Te6edf3logs
Tff7b72if Te6edf3searchTff7b72.Td2a8fflowerTb4b4b4(Tb4b4b4) Tff7b72in Te6edf3logTb4b4b4[Ta5d6ff"Ta5d6ffmessageTa5d6ff"Tb4b4b4]Tff7b72.Td2a8fflowerTb4b4b4(Tb4b4b4)
Tff7b72or Te6edf3searchTff7b72.Td2a8fflowerTb4b4b4(Tb4b4b4) Tff7b72in Te6edf3logTb4b4b4[Ta5d6ff"Ta5d6ffmoduleTa5d6ff"Tb4b4b4]Tff7b72.Td2a8fflowerTb4b4b4(Tb4b4b4)
Tb4b4b4]
Tff7b72if Te6edf3levelTb4b4b4:
Te6edf3logs Tff7b72= Tb4b4b4[Te6edf3log Tff7b72for Te6edf3log Tff7b72in Te6edf3logs Tff7b72if Te6edf3logTb4b4b4[Ta5d6ff"Ta5d6fflevelTa5d6ff"Tb4b4b4] Tff7b72== Te6edf3levelTb4b4b4]
Tff7b72if Te6edf3is_anomaly Tff7b72is Tff7b72not Tff7b72NoneTb4b4b4:
Te6edf3logs Tff7b72= Tb4b4b4[
Te6edf3log
Tff7b72for Te6edf3log Tff7b72in Te6edf3logs
Tff7b72if Te6edf3logTb4b4b4[Ta5d6ff"Ta5d6ffis_anomalyTa5d6ff"Tb4b4b4] Tff7b72== Tb4b4b4(T79c0ff1 Tff7b72if Te6edf3is_anomaly Tff7b72else T79c0ff0Tb4b4b4)
Tb4b4b4]
T8b949e# Sort descending
Te6edf3logsTff7b72.Td2a8ffsortTb4b4b4(Te6edf3keyTff7b72=Tff7b72lambda Te6edf3xTb4b4b4: Te6edf3xTb4b4b4[Ta5d6ff"Ta5d6fftimestampTa5d6ff"Tb4b4b4]Tb4b4b4, Te6edf3reverseTff7b72=Tff7b72TrueTb4b4b4)
Tff7b72return Te6edf3logsTb4b4b4[Te6edf3offset Tb4b4b4: Te6edf3offset Tff7b72+ Te6edf3limitTb4b4b4]
Tff7b72def Td2a8ffget_total_countTb4b4b4(Tff7b72selfTb4b4b4, Te6edf3searchTff7b72=Tff7b72NoneTb4b4b4, Te6edf3levelTff7b72=Tff7b72NoneTb4b4b4, Te6edf3moduleTff7b72=Tff7b72NoneTb4b4b4, Te6edf3is_anomalyTff7b72=Tff7b72NoneTb4b4b4)Tb4b4b4:
Tff7b72with Tff7b72selfTff7b72.Td2a8fflockTb4b4b4:
Tff7b72if Tff7b72selfTff7b72.Td2a8ffdatabaseTb4b4b4:
Tff7b72return Tff7b72selfTff7b72.Td2a8ffdatabaseTff7b72.Td2a8ffdebug_logsTff7b72.Td2a8ffget_total_countTb4b4b4(
Te6edf3searchTff7b72=Te6edf3searchTb4b4b4, Te6edf3levelTff7b72=Te6edf3levelTb4b4b4, Te6edf3moduleTff7b72=Te6edf3moduleTb4b4b4, Te6edf3is_anomalyTff7b72=Te6edf3is_anomaly
Tb4b4b4)
Tff7b72elseTb4b4b4:
Tff7b72return Tffa657lenTb4b4b4(Tff7b72selfTff7b72.Td2a8fflogs_bufferTb4b4b4)
──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────